package com.bootx.predict;


import com.bootx.predict.pojo.PredictPlugin;
import com.bootx.predict.pojo.PredictionResult;
import com.bootx.predict.pojo.RedPacketBatch;
import com.bootx.predict.pojo.RedPacketRecord;
import com.bootx.predict.util.PredictUtils;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * @author black
 * 冷热效应策略
 */
@Component("hotColdEffectStrategy")
public class HotColdEffectPredict extends PredictPlugin {

    @Override
    public String getName() {
        return "hotColdEffectStrategy";
    }

    @Override
    public List<PredictionResult> predict(List<RedPacketBatch> list, Set<Integer> indexes) {

        List<RedPacketRecord> history = PredictUtils.parseData(list);
        // 统计基础频率
        Map<Integer, List<Boolean>> map = new HashMap<>();
        Map<Integer, List<Integer>> timeMap = new HashMap<>();

        for (RedPacketRecord r : history) {
            map.computeIfAbsent(r.index, k -> new ArrayList<>()).add(PredictUtils.isAmountOdd(r.amount));
            timeMap.computeIfAbsent(r.index, k -> new ArrayList<>()).add(r.openTime);
        }
        List<PredictionResult> results = new ArrayList<>();
        for (int idx : indexes) {
            List<Boolean> allHistory = map.getOrDefault(idx, Collections.emptyList());
            List<Integer> allTimes = timeMap.getOrDefault(idx, Collections.emptyList());
            double baseProb = !allHistory.isEmpty() ? (double) allHistory.stream().filter(b -> b).count() / allHistory.size() : 0.5;
            // 热冷计算
            int hotStreak = 0;
            int coldStreak = 0;
            for (int i = allHistory.size() - 1; i >= 0; i--) {
                if (allHistory.get(i)) {
                    hotStreak++;
                    break;
                } else {
                    coldStreak++;
                }
            }
            double hotBonus = hotStreak * 0.05;
            double coldBonus = coldStreak * 0.02;

            double finalProb = baseProb + hotBonus + coldBonus;
            if (finalProb > 0.99) {
                finalProb = 0.99;
            }
            double avgOpenTime = allTimes.stream().mapToInt(Integer::intValue).average().orElse(0);
            results.add(new PredictionResult(idx, new BigDecimal(finalProb).setScale(2, RoundingMode.HALF_UP).doubleValue(), Double.valueOf(avgOpenTime+"").intValue()));
        }
        return results;
    }
}
